import Data.List ((\\))

type Range = (Int,Int)
data Direction = Lower | Upper deriving (Show)
type SeatPath = ([Direction],[Direction])
type Position = (Int,Int)

--------------------------------------------

parseChar :: Char -> Direction
parseChar ch = case ch of 
    'F' -> Lower
    'B' -> Upper
    'L' -> Lower
    'R' -> Upper

parseLine :: String -> SeatPath
parseLine string = (fbs, lrs)
    where
        fbs = map parseChar . take 7 $ string
        lrs = map parseChar . drop 7 $ string

parseInput :: String -> [SeatPath]
parseInput = map parseLine . lines

-----------------------------------------------------

lowerHalf :: Range -> Range
lowerHalf (low,up) = (low, newUp)
    where newUp = ((low + up + 1) `div` 2) - 1

upperHalf :: Range -> Range
upperHalf (low,up) = (newLow,up)
    where newLow = (low + up + 1) `div` 2

updateRange :: Range -> Direction -> Range
updateRange range direction = case direction of
    Lower -> lowerHalf range
    Upper -> upperHalf range

getSeat :: SeatPath -> Position
getSeat (fbs, lrs) = (row,col)
    where
        row = fst . foldl updateRange (0,127) $ fbs
        col = fst . foldl updateRange (0,7) $ lrs

getSeatID :: Position -> Int
getSeatID (row,col) = (row * 8 + col)

main = do
    input <- readFile "./input.txt"

    let seatIDs =  map getSeatID 
                 . map getSeat 
                 . parseInput $ input

    let missingSeatIDs = [0..1023] \\ seatIDs

    print . take 1 
          . filter (\x -> ((x+1) `elem` seatIDs) && ((x-1) `elem` seatIDs)) $ missingSeatIDs
